#include "stm32f10x.h"                  // Device header
#include "DS1302.h"
#include "Delay.h"
#include "OLED.h"

uint8_t DS1302_Time[] = {99, 12, 31, 12, 00, 00, 7, 12, 00, 00};//年、月、日、时、分、秒、星期、闹钟的时、分、秒
void DS1302_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = DS1302_CLK | DS1302_RSE | DS1302_DAT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_ResetBits(GPIOB, DS1302_CLK);
	GPIO_ResetBits(GPIOB, DS1302_RSE);
	GPIO_ResetBits(GPIOB, DS1302_DAT);
}

void DS1302_DATIN(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Pin = DS1302_DAT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void DS1302_DATOUT(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = DS1302_DAT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_ResetBits(GPIOB,DS1302_DAT);
}

void DS1302_WriteByte(uint8_t Command,uint8_t Data)
{
	DS1302_DATOUT();
	uint8_t i;
	GPIO_SetBits(GPIOB, DS1302_RSE);
	for(i=0;i<8;i++)
	{
		if(Command&(0x01<<i))
		{
			GPIO_SetBits(GPIOB, DS1302_DAT);
		}
		else
		{
			GPIO_ResetBits(GPIOB, DS1302_DAT);
		}
		GPIO_ResetBits(GPIOB, DS1302_CLK);	
		GPIO_SetBits(GPIOB, DS1302_CLK);	
		//一条指令1us>>200ns,因此由时序图不需要额外加延时
	}
	for(i=0;i<8;i++)
	{
		if(Data&(0x01<<i))
		{
			GPIO_SetBits(GPIOB, DS1302_DAT);
		}
		else
		{
			GPIO_ResetBits(GPIOB, DS1302_DAT);
		}
		GPIO_ResetBits(GPIOB, DS1302_CLK);	
		GPIO_SetBits(GPIOB, DS1302_CLK);	
		//一条指令1us>>200ns,因此由时序图不需要额外加延时
	}
	GPIO_ResetBits(GPIOB, DS1302_RSE);
	GPIO_ResetBits(GPIOB, DS1302_CLK);	
}
/*DS1302读操作，参数：（指令）*/
uint8_t DS1302_ReadByte(uint8_t Command)
{
	DS1302_DATOUT();
	uint8_t i,Data=0x00;
	Command|=0x01;//DS1302_WRITE_XXX最低为置1改为读入模式（DS1302_READ_XXX）
	GPIO_SetBits(GPIOB, DS1302_RSE);
	for(i=0;i<8;i++)
	{
		if(Command&(0x01<<i))
		{
			GPIO_SetBits(GPIOB, DS1302_DAT);
		}
		else
		{
			GPIO_ResetBits(GPIOB, DS1302_DAT);
		}
		GPIO_ResetBits(GPIOB, DS1302_CLK);	
		GPIO_SetBits(GPIOB, DS1302_CLK);	
		//一条指令1us>>200ns,因此由时序图不需要额外加延时
	}
	DS1302_DATIN();
	for(i=0;i<8;i++)
	{
		GPIO_SetBits(GPIOB, DS1302_CLK);	
		GPIO_ResetBits(GPIOB, DS1302_CLK);
		if(GPIO_ReadInputDataBit(GPIOB, DS1302_DAT) == 1){Data|=(0x01<<i);}//单片机准备读取DS1302_IO
	}
	GPIO_ResetBits(GPIOB, DS1302_RSE);
	GPIO_ResetBits(GPIOB, DS1302_CLK);	
	
	return Data;
}

void DS1302_SetTime(void)//十进制转十六进制
{
	DS1302_WriteByte(DS1302_WRITE_WP, 0x00);//关闭写保护
	DS1302_WriteByte(DS1302_WRITE_YEAR, DS1302_Time[0]/10*16+DS1302_Time[0]%10);
	DS1302_WriteByte(DS1302_WRITE_MONTH, DS1302_Time[1]/10*16+DS1302_Time[1]%10);
	DS1302_WriteByte(DS1302_WRITE_DATE, DS1302_Time[2]/10*16+DS1302_Time[2]%10);
	DS1302_WriteByte(DS1302_WRITE_HOUR, DS1302_Time[3]/10*16+DS1302_Time[3]%10);
	DS1302_WriteByte(DS1302_WRITE_MINUTE, DS1302_Time[4]/10*16+DS1302_Time[4]%10);
	DS1302_WriteByte(DS1302_WRITE_SECOND, DS1302_Time[5]/10*16+DS1302_Time[5]%10);
	DS1302_WriteByte(DS1302_WRITE_DAY, DS1302_Time[6]/10*16+DS1302_Time[6]%10);

	DS1302_WriteByte(DS1302_WRITE_WP, 0x80);//开启写保护
}

void DS1302_ReadTime(void)//十六进制转十进制
{
	uint8_t temp;
	temp=DS1302_ReadByte(DS1302_WRITE_YEAR);
	DS1302_Time[0]=temp/16*10+temp%16;
	temp=DS1302_ReadByte(DS1302_WRITE_MONTH);
	DS1302_Time[1]=temp/16*10+temp%16;
	temp=DS1302_ReadByte(DS1302_WRITE_DATE);
	DS1302_Time[2]=temp/16*10+temp%16;
	temp=DS1302_ReadByte(DS1302_WRITE_HOUR);
	DS1302_Time[3]=temp/16*10+temp%16;
	temp=DS1302_ReadByte(DS1302_WRITE_MINUTE);
	DS1302_Time[4]=temp/16*10+temp%16;
	temp=DS1302_ReadByte(DS1302_WRITE_SECOND);
	DS1302_Time[5]=temp/16*10+temp%16;
	temp=DS1302_ReadByte(DS1302_WRITE_DAY);
	DS1302_Time[6]=temp/16*10+temp%16;
}

void TimeShow(void)
{
	DS1302_ReadTime();
	OLED_ShowNum(2, 6, DS1302_Time[0], 2);
	OLED_ShowNum(2, 9, DS1302_Time[1], 2);
	OLED_ShowNum(2, 12, DS1302_Time[2], 2);
	OLED_ShowNum(2, 16, DS1302_Time[6], 1);
	
	OLED_ShowNum(3, 6, DS1302_Time[3], 2);
	OLED_ShowNum(3, 9, DS1302_Time[4], 2);
	OLED_ShowNum(3, 12, DS1302_Time[5], 2);
}
